package com.zou.practice.aspect;

import com.alibaba.fastjson.JSON;
import com.zou.practice.error.ExceptionEnum;
import com.zou.practice.error.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolationException;

/**
 * @author zouyaowen
 * @date 2020-08-18
 */
@RestControllerAdvice
@Slf4j
public class ExceptionAdvice {
    /**
     * 异常拦截
     *
     * @param exception 异常对象
     * @return 统一处理异常后的返回值
     */
    @ExceptionHandler({Exception.class})
    @ResponseBody
    public CommonResponse<Object> serviceExceptionHandler(Exception exception) {
        CommonResponse<Object> res = new CommonResponse<>();
        try {
            throw exception;
        } catch (ConstraintViolationException e) {
            log.error("参数异常", e);
            res.setCode(ExceptionEnum.PARAM_ERROR.getCode());
            String message = e.getMessage();
            res.setMessage(message.substring(message.indexOf(" ") + 1));
            return res;
        } catch (NoHandlerFoundException e) {
            log.info("资源不存在,请求资源为=[{}]", e.getRequestURL());
            log.info("资源不存在,请求方法为=[{}]", e.getHttpMethod());
            res.setCode(ExceptionEnum.NOT_FOUND.getCode());
            res.setMessage(ExceptionEnum.NOT_FOUND.getMessage());
            return res;
        } catch (HttpRequestMethodNotSupportedException e) {
            log.info("请求方法不支持,请求method为=[{}]", e.getMethod());
            log.info("请求方法不支持,请求支持的Methods为=[{}]", JSON.toJSONString(e.getSupportedMethods()));
            res.setCode(ExceptionEnum.HTTP_METHOD_ERROR.getCode());
            res.setMessage(ExceptionEnum.HTTP_METHOD_ERROR.getMessage());
            return res;
        } catch (ServiceException e) {
            res.setCode(e.getErrorCode());
            res.setMessage(e.getMessage());
            return res;
        } catch (Exception e) {
            log.error("服务器内部异常", e);
            res.setCode(ExceptionEnum.INTERNAL_ERROR.getCode());
            res.setMessage(ExceptionEnum.INTERNAL_ERROR.getMessage());
            return res;
        }
    }
}
